package org.zjx.message.messages;

import com.alibaba.fastjson2.JSON;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.zjx.message.AbstractMessage;

@EqualsAndHashCode(callSuper = true)
@Data
public class RpcRequest extends AbstractMessage {
    private static final Logger logger = LoggerFactory.getLogger(RpcRequest.class);
    private String className;
    private String methodName;
    private String[] parameterTypeNames;
    private Object[] parameters; // 原始参数
    private transient Class<?>[] resolvedParameterTypes; // 缓存已解析的类型

    /**
     * 获取参数类型并确保参数值类型匹配
     */
    public Class<?>[] getParameterTypes() throws ClassNotFoundException {
        if (resolvedParameterTypes != null) {
            return resolvedParameterTypes;
        }

        if (parameterTypeNames == null) {
            return null;
        }

        resolvedParameterTypes = new Class[parameterTypeNames.length];
        for (int i = 0; i < parameterTypeNames.length; i++) {
            resolvedParameterTypes[i] = resolveClass(parameterTypeNames[i]);
            parameters[i] = convertParameter(parameters[i], resolvedParameterTypes[i]);
        }
        return resolvedParameterTypes;
    }

    private Class<?> resolveClass(String className) throws ClassNotFoundException {
        // 处理基本类型
        return switch (className) {
            case "int" -> int.class;
            case "long" -> long.class;
            case "double" -> double.class;
            case "float" -> float.class;
            case "boolean" -> boolean.class;
            case "char" -> char.class;
            case "byte" -> byte.class;
            case "short" -> short.class;
            case "void" -> void.class;
            default -> Class.forName(className);
        };
    }

    private Object convertParameter(Object param, Class<?> targetType) {
        if (param == null || targetType.isInstance(param)) {
            return param;
        }

        // 处理枚举参数
        if (targetType.isEnum()) {
            if (param instanceof String) {
                try {
                    @SuppressWarnings("unchecked")
                    Class<? extends Enum> enumType = (Class<? extends Enum>) targetType;
                    return Enum.valueOf(enumType, (String)param);
                } catch (IllegalArgumentException e) {
                    logger.warn("Enum conversion failed for {}: {}", targetType.getName(), param);
                }
            } else if (param instanceof Enum) {
                return ((Enum<?>)param).name(); // 确保枚举被序列化为名称
            }
            return param;
        }


        // 处理JSON字符串到对象的转换
        if (param instanceof String jsonStr && jsonStr.startsWith("{")) {
            try {
                return JSON.parseObject(jsonStr, targetType);
            } catch (Exception e) {
                logger.warn("Failed to parse JSON to {}: {}", targetType.getName(), jsonStr);
            }
        }

        // 处理基本类型转换
        if (targetType.isPrimitive() || Number.class.isAssignableFrom(targetType)) {
            return convertNumber(param, targetType);
        }

        // 处理字符串转换
        if (targetType == String.class) {
            return param.toString();
        }

        // 其他情况尝试JSON转换
        try {
            return JSON.parseObject(JSON.toJSONString(param), targetType);
        } catch (Exception e) {
            logger.warn("Parameter conversion failed from {} to {}",
                    param.getClass().getName(), targetType.getName());
            return param; // 最后尝试原始值
        }
    }

    private Object convertNumber(Object value, Class<?> targetType) {
        if (value instanceof Number number) {
            if (targetType == int.class || targetType == Integer.class) {
                return number.intValue();
            } else if (targetType == long.class || targetType == Long.class) {
                return number.longValue();
            } else if (targetType == double.class || targetType == Double.class) {
                return number.doubleValue();
            } else if (targetType == float.class || targetType == Float.class) {
                return number.floatValue();
            } else if (targetType == byte.class || targetType == Byte.class) {
                return number.byteValue();
            } else if (targetType == short.class || targetType == Short.class) {
                return number.shortValue();
            }
        } else if (value instanceof String str) {
            try {
                if (targetType == int.class || targetType == Integer.class) {
                    return Integer.parseInt(str);
                } else if (targetType == long.class || targetType == Long.class) {
                    return Long.parseLong(str);
                } else if (targetType == double.class || targetType == Double.class) {
                    return Double.parseDouble(str);
                } else if (targetType == float.class || targetType == Float.class) {
                    return Float.parseFloat(str);
                } else if (targetType == byte.class || targetType == Byte.class) {
                    return Byte.parseByte(str);
                } else if (targetType == short.class || targetType == Short.class) {
                    return Short.parseShort(str);
                }
            } catch (NumberFormatException e) {
                logger.warn("Number format exception: {}", str);
            }
        }
        return value; // 无法转换则返回原值
    }
}